/*
 * @Descripttion: dva的实现
 * @Author: lukasavage
 * @Date: 2022-10-19 16:42:18
 * @LastEditors: lukasavage
 * @LastEditTime: 2022-10-19 16:42:55
 * @FilePath: \react-demo\src\dva\index.js
 */
import React from 'react';
import ReactDOM from 'react-dom';
import { createStore, combineReducers } from 'redux';
import { connect, Provider } from 'react-redux';
import prefixNamespace from './prefixNamespace';
export { connect };

function dva() {
    const app = {
        _models: [],
        model,
        router,
        _router: null,
        start,
        createAction
    }
    const initialReducers = {};
    function model(model) {
        const prefixedModel = prefixNamespace(model);
        app._models.push(prefixedModel);
        return prefixedModel;
    }
    function router(router) {
        app._router = router;
    }
    function createAction() {
        let actionCreators = {};
        for (const model of app._models) {
            let { reducers } = model;
            for (let key in reducers) {
                // counter/add =>  action {type:'counter/add'}
                actionCreators[key] = () => ({ type: key })
            }
        }
        return actionCreators;
    }
    function start(root) {
        for (const model of app._models) {
            initialReducers[model.namespace] = getReducer(model);
        }
        let rootReducer = createReducer();
        let store = createStore(rootReducer);
        ReactDOM.render(<Provider store={store}>{app._router()}</Provider>, document.querySelector(root));
        function createReducer() {
            return combineReducers(initialReducers);
        }
    }

    return app;
}

function getReducer(model) {
    let { reducers, state: defaultState } = model;
    let reducer = (state = defaultState, action) => {
        let reducer = reducers[action.type];
        if (reducer) {
            return reducer(state, action);
        }
        return state;
    }
    return reducer;
}

export default dva;